# -*- coding: utf-8 -*-

""" 源中的相变项 """

import numpy as np

from utils.constant import *
from utils.numeric import *

class PhaseTransition:
    """
    相变源项
    
    Attributes:
        standard_input: dict 标准化输入
        entrainment_rate_segment_previous_time_step: np.ndarray 前一个时间步的夹带率
    """
    def __init__(self, standard_input: dict, entrainment_rate_segment_previous_time_step: np.ndarray):
        self.standard_input = standard_input
        self.entrainment_rate_segment_previous_time_step = entrainment_rate_segment_previous_time_step

    @staticmethod
    def _cal_liquid_vapour_mass_transfer_rate(
        rho_g_segment: np.ndarray,
        V_sg_segment: np.ndarray,
        rho_L_segment: np.ndarray,
        V_sL_segment: np.ndarray,
        V_D_segment: np.ndarray,
        alpha_D_segment: np.ndarray,
        gas_mass_fraction: np.ndarray,
        dx: float,
    ) -> np.ndarray:
        """ 计算气相携带率

        Args:
            rho_g_segment : np.ndarray 气体密度
            V_sg_segment : np.ndarray  气体折算速度
            rho_L_segment : np.ndarray 液体密度
            V_sL_segment : np.ndarray 液体折算速度
            V_D_segment : np.ndarray  液滴速度
            alpha_D_segment : np.ndarray 液滴横截面分数
            Rs_g_segment : np.ndarray 气相的平衡质量分数
            dx : float 网格大小

        Returns:
            np.ndarray 气相携带率
        """
        liquid_vapour_mass_transfer_rate = np.zeros_like(rho_g_segment)
        liquid_vapour_mass_transfer_rate[1:-1] = difference((rho_g_segment * V_sg_segment + rho_L_segment * V_sL_segment+ rho_L_segment * V_D_segment * alpha_D_segment) * gas_mass_fraction, dx, DifferenceMode.CDMd.value)
        liquid_vapour_mass_transfer_rate[0] = liquid_vapour_mass_transfer_rate[1]
        liquid_vapour_mass_transfer_rate[-1] = liquid_vapour_mass_transfer_rate[-2]

        return liquid_vapour_mass_transfer_rate

    @staticmethod
    def _cal_interface_velocity_from_liquid_to_droplet(V_L_segment: np.ndarray) -> np.ndarray:
        """ 计算管道中的相界面流速, 乃液相进入液滴相时的速度, 
            由于惯性,通常这个速度约等于液相速度
        Args:
            V_L_segment : np.ndarray 液相速度

        Returns:
            V_i_segment: np.ndarray
        """
        V_i_segment = V_L_segment
        return V_i_segment

    @staticmethod
    def _cal_transition_velocity_from_liquid_film(
        liquid_vapour_mass_transfer_rate: np.ndarray, V_L_segment: np.ndarray, V_g_segment: np.ndarray
    ) -> np.ndarray:
        """ 计算从液膜蒸发或者凝结的速度

        Args:
            liquid_vapour_mass_transfer_rate : np.ndarray 气液相间质量传递率
            V_L_segment : np.ndarray 液相速度
            V_g_segment : np.ndarray 气相速度

        Returns:
            np.ndarray: 从液膜蒸发或者凝结的速度
        """
        transition_velocity_from_liquid_film = np.where(liquid_vapour_mass_transfer_rate > 0, V_L_segment, V_g_segment)
        return transition_velocity_from_liquid_film

    @staticmethod
    def _cal_transition_velocity_from_droplet(
        liquid_vapour_mass_transfer_rate: np.ndarray,
        V_D_segment: np.ndarray,
        V_g_segment: np.ndarray,
    ) -> np.ndarray:
        """ 计算从液滴蒸发或者凝结的速度

        Args:
            liquid_vapour_mass_transfer_rate : np.ndarray 气液相间质量传递率
            V_D_segment : np.ndarray 液滴速度
            V_g_segment : np.ndarray 气相速度

        Returns:
            np.ndarray: 从液滴蒸发或者凝结的速度
        """
        transition_velocity_from_droplet = np.where(liquid_vapour_mass_transfer_rate > 0, V_D_segment, V_g_segment)
        return transition_velocity_from_droplet

    @staticmethod
    def _cal_entrainment_rate(
        V_sg_segment: np.ndarray,
        V_sL_segment: np.ndarray,
        liquid_viscosity_segment: np.ndarray,
        gas_viscosity_segment: np.ndarray,
        rho_L_segment: np.ndarray,
        rho_g_segment: np.ndarray,
        D_segment: float,
        liquid_surface_tension_segment: np.ndarray,
    ) -> np.ndarray:
        """ 计算液滴夹带率

        Args:
            V_sg_segment : np.ndarray  气体折算速度
            V_sL_segment : np.ndarray 液体折算速度
            liquid_viscosity_segment : np.ndarray 液相动力粘度
            gas_viscosity_segment : np.ndarray 气相动力粘度
            rho_L_segment : np.ndarray 液相密度
            rho_g_segment : np.ndarray 气相密度
            D_segment: float 管的内径
            liquid_surface_tension_segment : np.ndarray 气液相表面张力

        Returns:
            np.ndarray F_E夹带率
        """
        mineps = 1e-15
        We_SG = (rho_g_segment * np.abs(V_sg_segment) ** 2 * D_segment) / (liquid_surface_tension_segment + mineps)
        Fr_SL = np.abs(V_sL_segment) / (np.sqrt(Physics.g.value * D_segment) + mineps)
        Fr_SL_exp = np.where(Fr_SL == 0, 0, Fr_SL ** -0.92)

        Re_SL = rho_L_segment * np.abs(V_sL_segment) * D_segment / (liquid_viscosity_segment + mineps)
        Re_SG = rho_g_segment * np.abs(V_sg_segment) * D_segment / (gas_viscosity_segment + mineps)
        Re_SG_exp = np.where(Re_SG == 0, 0, (Re_SG + 1e-12) ** -1.24)

        MED = (
                0.003
                * We_SG ** 1.8
                * Fr_SL_exp
                * Re_SL ** 0.7
                * Re_SG_exp
                * (rho_L_segment / (rho_g_segment + mineps)) ** 0.38
                * (liquid_viscosity_segment / (gas_viscosity_segment + mineps)) ** 0.97
        )
        entrainment_rate_segment = MED / (1 + MED)
        # return entrainment_rate_segment
        return np.zeros_like(V_sg_segment)


    @staticmethod
    def _cal_liquid_to_droplet_mass_transfer_rate(
        rho_L_segment: np.ndarray,
        delta_entrainment_rate_segment: np.ndarray,
        V_L_segment: np.ndarray,
        cross_section_area_segment: np.ndarray,
        alpha_L_segment: np.ndarray,
    ) -> np.ndarray:
        """ 计算液相到液滴的质量传递率

        Args:
            rho_L_segment : np.ndarray 液体密度
            delta_entrainment_rate_segment : np.ndarray 夹带率与前一个夹带率的差值
            V_L_segment : np.ndarray 液体速度
            cross_section_area_segment : np.ndarray 管截面面积

        Returns:
            np.ndarray 液相到液滴的质量传递率
        """
        liquid_to_droplet_mass_transfer_rate = np.where(delta_entrainment_rate_segment > 0, rho_L_segment * delta_entrainment_rate_segment * V_L_segment * cross_section_area_segment * alpha_L_segment, 0)     
        # return liquid_to_droplet_mass_transfer_rate
        return np.zeros_like(rho_L_segment)


    @staticmethod
    def _cal_droplet_to_liquid_mass_transfer_rate(
        rho_L_segment: np.ndarray,
        delta_entrainment_rate_segment: np.ndarray,
        V_L_segment: np.ndarray,
        cross_section_area_segment: np.ndarray,
        alpha_L_segment: np.ndarray,
    ) -> np.ndarray:
        """ 计算液滴到液相的质量传递率

        Args:
            rho_L_segment : np.ndarray 液体密度
            delta_entrainment_rate_segment : np.ndarray 夹带率与前一个夹带率的差值
            V_L_segment : np.ndarray 液体速度
            cross_section_area_segment : np.ndarray 管截面面积

        Returns:
            np.ndarray 液滴到液相的质量传递率
        """

        droplet_to_liquid_mass_transfer_rate = np.where(delta_entrainment_rate_segment < 0, - rho_L_segment * delta_entrainment_rate_segment * V_L_segment * cross_section_area_segment * alpha_L_segment, 0)
        # return droplet_to_liquid_mass_transfer_rate
        return np.zeros_like(rho_L_segment)


    @staticmethod
    def _cal_droplet_velocity(
        entrainment_rate_segment: np.ndarray, alpha_D_segment: np.ndarray, alpha_L_segment: np.ndarray, V_L_segment: np.ndarray
    ) -> np.ndarray:
        """ 计算液滴速度

        Args:
            entrainment_rate_segment : np.ndarray 夹带率
            alpha_D_segment : np.ndarray 液滴横截面分数
            alpha_L_segment : np.ndarray 液体横截面分数
            V_L_segment : np.ndarray 液体速度

        Returns:
            np.ndarray 液滴速度
        """
        droplet_velocity = np.where(
            alpha_D_segment == 0, 0, entrainment_rate_segment * alpha_L_segment * V_L_segment / (alpha_D_segment - entrainment_rate_segment * alpha_D_segment + 1e-15)
        )
        # return droplet_velocity
        return np.zeros_like(V_L_segment)

    def cal_phase_transition_source(self):
        """ 计算相变源项

        Returns:
            liquid_vapour_mass_transfer_rate: np.ndarray 气液相间质量传递率
            V_i_segment: np.ndarray 相界面速度
            transition_velocity_from_liquid_film: np.ndarray 从液膜蒸发或者凝结的速度
            transition_velocity_from_droplet: np.ndarray 从液滴蒸发或者凝结的速度
            entrainment_rate_segment: np.ndarray 夹带率
            liquid_to_droplet_mass_transfer_rate: np.ndarray 液相到液滴的质量传递率
            droplet_to_liquid_mass_transfer_rate: np.ndarray 液滴到液相的质量传递率
            droplet_velocity: np.ndarray 液滴速度
        """
        # 获取输入参数
        rho_g_segment = self.standard_input['rho_g_segment']
        # 等效气相速度
        V_sg_segment = self.standard_input['V_sg_segment']
        rho_L_segment = self.standard_input['rho_L_segment']
        # 等效液相速度
        V_sL_segment = self.standard_input['V_sL_segment']
        V_D_segment = self.standard_input['V_D_segment']
        alpha_D_segment = self.standard_input['alpha_D_segment']
        # Rs_g
        gas_mass_fraction = self.standard_input['gas_mass_fraction_segment']
        dx = self.standard_input['dx']
        # mu_L
        liquid_viscosity_segment = self.standard_input['liquid_viscosity_segment']
        # mu_g
        gas_viscosity_segment = self.standard_input['gas_viscosity_segment']
        D_segment = self.standard_input['D_segment']
        # sigma
        liquid_surface_tension_segment = self.standard_input['liquid_surface_tension_segment']
        cross_section_area_segment = self.standard_input['cross_section_area_segment']
        alpha_L_segment = self.standard_input['alpha_L_segment']
        V_L_segment = self.standard_input['V_L_segment']
        V_g_segment = self.standard_input['V_g_segment']

        # 计算相变源项
        liquid_vapour_mass_transfer_rate = self._cal_liquid_vapour_mass_transfer_rate(rho_g_segment, V_sg_segment, rho_L_segment, V_sL_segment, V_D_segment, alpha_D_segment, gas_mass_fraction, dx)
        
        V_i_segment = self._cal_interface_velocity_from_liquid_to_droplet(V_L_segment)
        
        transition_velocity_from_liquid_film = self._cal_transition_velocity_from_liquid_film(liquid_vapour_mass_transfer_rate, V_L_segment, V_g_segment)
        
        transition_velocity_from_droplet = self._cal_transition_velocity_from_droplet(liquid_vapour_mass_transfer_rate, V_D_segment, V_g_segment)
        
        entrainment_rate_segment = self._cal_entrainment_rate(V_sg_segment, V_sL_segment, liquid_viscosity_segment, gas_viscosity_segment, rho_L_segment, rho_g_segment, D_segment, liquid_surface_tension_segment)
        
        # 不作返回
        delta_entrainment_rate_segment = entrainment_rate_segment - self.entrainment_rate_segment_previous_time_step

        liquid_to_droplet_mass_transfer_rate = self._cal_liquid_to_droplet_mass_transfer_rate(rho_L_segment, delta_entrainment_rate_segment, V_L_segment, cross_section_area_segment, alpha_L_segment)
        droplet_to_liquid_mass_transfer_rate = self._cal_droplet_to_liquid_mass_transfer_rate(rho_L_segment, delta_entrainment_rate_segment, V_L_segment, cross_section_area_segment, alpha_L_segment)
        droplet_velocity = self._cal_droplet_velocity(entrainment_rate_segment, alpha_D_segment, alpha_L_segment, V_L_segment)

        return liquid_vapour_mass_transfer_rate, V_i_segment, transition_velocity_from_liquid_film, transition_velocity_from_droplet, entrainment_rate_segment, liquid_to_droplet_mass_transfer_rate, droplet_to_liquid_mass_transfer_rate, droplet_velocity






